home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / comm / wnos5src.zip / NRS.C < prev    next >
Text File  |  1993-08-09  |  5KB  |  188 lines

  1. /* This module implements the serial line framing method used by
  2.  * net/rom nodes.  This allows the net/rom software to talk to
  3.  * an actual net/rom over its serial interface, which is useful
  4.  * if we want to do packet switching for multi-line wormholes.
  5.  * Dan Frank, W9NK
  6.  */
  7. #include <stdio.h>
  8. #include "global.h"
  9. #include "config.h"
  10. #ifdef NRS
  11. #include "mbuf.h"
  12. #include "iface.h"
  13. #include "pktdrvr.h"
  14. #include "ax25.h"
  15. #include "nrs.h"
  16. #include "asy.h"
  17. #include "trace.h"
  18. #include "commands.h"
  19.  
  20. static struct mbuf * near nrs_encode __ARGS((struct mbuf *bp));
  21. static struct mbuf * near nrs_decode __ARGS((int dev,char c));
  22.  
  23. /* control structures, sort of overlayed on async control blocks */
  24. struct nrs Nrs[ASY_MAX];
  25.  
  26. /* Send a raw net/rom serial frame */
  27. int
  28. nrs_raw(struct iface *iface,struct mbuf *bp)
  29. {
  30.     struct mbuf *bp1 = nrs_encode(bp);
  31.     dump(iface,IF_TRACE_OUT,CL_AX25,bp) ;
  32.  
  33.     return Nrs[iface->xdev].send(iface->dev,bp1);
  34. }
  35.  
  36. /* Encode a packet in net/rom serial format */
  37. static struct mbuf * near
  38. nrs_encode(struct mbuf *bp)
  39. {
  40.     int c;
  41.     unsigned char csum = 0 ;
  42.  
  43.     /* Allocate output mbuf that's twice as long as the packet.
  44.      * This is a worst-case guess (consider a packet full of STX's!)
  45.      * Add five bytes for STX, ETX, checksum, and two nulls.
  46.      */
  47.     struct mbuf *lbp = alloc_mbuf((int16)(2*len_p(bp) + 5));
  48.     char *cp = lbp->data;
  49.  
  50.     *cp++ = STX ;
  51.  
  52.     /* Copy input to output, escaping special characters */
  53.     while((c = PULLCHAR(&bp)) != -1){
  54.         switch(c){
  55.         case STX:
  56.         case ETX:
  57.         case DLE:
  58.             *cp++ = DLE;
  59.             /* notice drop through to default */
  60.         default:
  61.             *cp++ = c;
  62.         }
  63.         csum += c;
  64.     }
  65.     *cp++ = ETX;
  66.     *cp++ = csum ;
  67.     *cp++ = NUL ;
  68.     *cp++ = NUL ;
  69.  
  70.     lbp->cnt = cp - lbp->data;
  71.     return lbp;
  72. }
  73.  
  74. /* Process incoming bytes in net/rom serial format
  75.  * When a buffer is complete, return it; otherwise NULLBUF
  76.  */
  77. static struct mbuf * near
  78. nrs_decode(int dev,char c)
  79. {
  80.     struct mbuf *bp;
  81.     struct nrs *sp = &Nrs[dev];
  82.  
  83.     switch(sp->state) {
  84.         case NRS_INTER:
  85.             if (uchar(c) == STX) {    /* look for start of frame */
  86.                 sp->state = NRS_INPACK ;    /* we're in a packet */
  87.                 sp->csum = 0 ;                /* reset checksum */
  88.             }
  89.             return NULLBUF ;
  90.         case NRS_CSUM:
  91.             bp = sp->rbp ;
  92.             sp->rbp = NULLBUF ;
  93.             sp->rcnt = 0 ;
  94.             sp->state = NRS_INTER ;    /* go back to inter-packet state */
  95.             if (sp->csum == uchar(c)) {
  96.                 sp->packets++ ;
  97.             } else {
  98.                 free_p(bp) ;    /* drop packet with bad checksum */
  99.                 bp = NULLBUF;
  100.                 sp->errors++ ;    /* increment error count */
  101.             }
  102.             return bp ;
  103.         case NRS_ESCAPE:
  104.             sp->state = NRS_INPACK ;    /* end of escape */
  105.             break ;            /* this will drop through to char processing */
  106.         case NRS_INPACK:
  107.             switch (uchar(c)) {
  108.             /* If we see an STX in a packet, assume that previous */
  109.             /* packet was trashed, and start a new packet */
  110.             case STX:
  111.                 free_p(sp->rbp) ;
  112.                 sp->rbp = NULLBUF ;
  113.                 sp->rcnt = 0 ;
  114.                 sp->csum = 0 ;
  115.                 sp->errors++ ;
  116.                 return NULLBUF ;
  117.             case ETX:
  118.                 sp->state = NRS_CSUM ;    /* look for checksum */
  119.                 return NULLBUF ;
  120.             case DLE:
  121.                 sp->state = NRS_ESCAPE ;
  122.                 return NULLBUF ;
  123.             }
  124.     }
  125.     /* If we get to here, it's with a character that's part of the packet.
  126.      * Make sure there's space for it.
  127.      */
  128.     if(sp->rbp == NULLBUF){
  129.         /* Allocate first mbuf for new packet */
  130.         sp->rbp1 = sp->rbp = alloc_mbuf(NRS_ALLOC);
  131.         sp->rcp = sp->rbp->data;
  132.     } else if(sp->rbp1->cnt == NRS_ALLOC){
  133.         /* Current mbuf is full; link in another */
  134.         sp->rbp1->next = alloc_mbuf(NRS_ALLOC);
  135.         sp->rbp1 = sp->rbp1->next;
  136.         sp->rcp = sp->rbp1->data;
  137.     }
  138.     /* Store the character, increment fragment and total
  139.      * byte counts
  140.      */
  141.     *sp->rcp++ = c;
  142.     sp->rbp1->cnt++;
  143.     sp->rcnt++;
  144.     sp->csum += uchar(c) ;    /* add to checksum */
  145.     return NULLBUF;
  146. }
  147.  
  148. /* Process net/rom serial line I/O */
  149. void
  150. nrs_recv(int dev,void *v1,void *v2)
  151. {
  152.     char c;
  153.     struct mbuf *bp, *nbp;
  154.     struct phdr phdr;
  155.  
  156.     /* Process any pending input */
  157.     for(;;){
  158.         c = Nrs[dev].get(Nrs[dev].iface->dev);
  159.         if((bp = nrs_decode(dev,c)) == NULLBUF)
  160.             continue;
  161.         nbp = pushdown(bp,sizeof(struct phdr));
  162.         phdr.iface = Nrs[dev].iface;
  163.         phdr.type = CL_AX25;
  164.         memcpy(nbp->data,(char *)&phdr,sizeof(struct phdr));
  165.         enqueue(&Hopper,nbp);
  166.     }
  167.  
  168. }
  169.  
  170. /* donrstat:  display status of active net/rom serial interfaces */
  171. int
  172. donrstat(int argc,char **argv,void *p)
  173. {
  174.     struct nrs *np ;
  175.     int i = 0 ;
  176.  
  177.     tputs("Interface   RcvB  NumReceived  CSumErrors\n") ;
  178.  
  179.     for(np = Nrs ; i < ASY_MAX ; i++, np++)
  180.         if(np->iface != NULLIF)
  181.             tprintf(" %8s   %4d   %10lu  %10lu\n",
  182.                 np->iface->name, np->rcnt,np->packets,np->errors);
  183.  
  184.     return 0 ;
  185. }
  186.  
  187. #endif /* NRS */
  188.